package security;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Base64;

public class HMAC {
	
	/**
	 * Créer une emprinte de la forme :
	 * HMAC (K,m) = H ((K ⊕ opad) ∥ H ((K ⊕ ipad) ∥ m))
	 * @param pass
	 * @param salt
	 * @return l'emprinte
	 * @throws UnsupportedEncodingException 
	 */
	public final static byte[] hmac_sha256(String pass, byte[] salt) {
		MessageDigest md;
		byte[] dg = null;
		String Kopad = "";
		String Kipad = "";
		StringBuilder sb = new StringBuilder();

		char iPad = 0x36;
		char oPad = 0x5c;
		
		String formated_salt = new String(salt);
		
		for(int i = 0; i < pass.length(); i++)
		    sb.append((char)(pass.charAt(i) ^ iPad));
		Kipad = sb.toString();
		
		for(int i = 0; i < pass.length(); i++)
		    sb.append((char)(pass.charAt(i) ^ oPad));
		Kopad = sb.toString();
		
		try {
			md = MessageDigest.getInstance("SHA-256");
			dg = md.digest((Kopad + new String(md.digest((Kipad+formated_salt).getBytes("UTF-8")), "UTF-8") ).getBytes("UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dg;
	}
	
	/**
	 * Converti un tableau de byte en String codée en base 64.
	 * @param tab
	 * @return
	 */
	public static String encodeBase64(byte[] tab) {
		return new Base64().encodeToString(tab);
	}
	
	public static byte[] decodeBase64(String str) {
		return new Base64().decode(str.getBytes());
	}
	
	
	// tests
	public static void main(String[] args) {
		byte[] salt = null;
		byte[] key = null;
		String tmp = "";
		try {
			salt = RandomGenerator.generateSalt(32);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		
		key = hmac_sha256("admin", salt);
		System.out.println("sel\t\t"+encodeBase64(salt));
		System.out.println("emprinte\t"+new String(key));
		tmp = encodeBase64(key);
		System.out.println("emprinte\t"+tmp);
		System.out.println("emprinte\t"+new String(decodeBase64(tmp)));
	}

}
